package com.probox.apiModules.controller.customer;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.probox.common.core.constant.Constants;
import com.probox.common.core.enums.CustomerFundBizTypeEnum;
import com.probox.common.core.enums.DataStatus;
import com.probox.common.core.exception.CustomException;
import com.probox.common.core.exception.WechatException;
import com.probox.common.core.utils.SecurityUtils;
import com.probox.common.core.utils.StringUtils;
import com.probox.common.core.web.controller.BaseController;
import com.probox.common.core.web.domain.AjaxResult;
import com.probox.common.entity.domain.customer.*;
import com.probox.common.entity.query.BaseQuery;
import com.probox.common.entity.vo.customer.CustomerLevelPrivleageVo;
import com.probox.common.entity.vo.customer.CustomerLevelVo;
import com.probox.common.security.annotation.VerifyAuthorize;
import com.probox.common.entity.vo.CustomerFundVo;
import com.probox.customer.api.domain.*;
import com.probox.common.entity.service.customer.*;
import com.probox.common.entity.service.wechat.IWechatAuthorizationInfoService;
import com.probox.common.entity.vo.customer.CustomerInfoVo;
import com.probox.common.entity.vo.customer.open.CustomerPhoneLoginVo;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 开放给外部访问的客户服务
 */
@Api(value = "客户模块", tags = {"客户信息前端操作接口"})
@RestController
@RequestMapping("/customer/openCustomer")
public class OpenCustomerController extends BaseController {
    @Autowired
    private ICustomerInfoService customerInfoService;

    @Autowired
    private ICustomerInfoAccountService customerInfoAccountService;

    @Autowired
    private ICustomerInfoAccountTokenService customerInfoAccountTokenService;

    @Autowired
    private ICustomerLevelService customerLevelService;

    @Autowired
    private ICustomerFundDetailService customerFundDetailService;

    @Autowired
    private IWechatAuthorizationInfoService wechatAuthorizationInfoService;

    @Autowired
    private ICustomerFundService customerFundService;





    /**
     * 客户账号注册
     */
    @ApiOperation(value = "客户注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "用户名", value = "accountName", paramType = "String", required = true),
            @ApiImplicitParam(name = "密码", value = "accountPassword", paramType = "String", required = true),
            @ApiImplicitParam(name = "手机号", value = "phone", paramType = "String", required = true),
            @ApiImplicitParam(name = "验证码", value = "code", paramType = "String", required = true)
    })
    @PostMapping("/register")
    public AjaxResult customerRegister(@RequestBody CustomerInfoAccountVo account) {
        String userName = account.getAccountName();
        String userPassword = account.getAccountPassword();
        String phone = account.getPhone();
        if (StringUtils.isEmpty(userName)) {
            throw new CustomException("用户名不能为空");
        }
        if (StringUtils.isEmpty(userPassword)) {
            throw new CustomException("密码不能为空");
        }
        if (StringUtils.isEmpty(phone)) {
            throw new CustomException("手机号码不能为空");
        }
        Boolean isCrate = customerInfoAccountService.createCustomerAccount(account);
        if (isCrate) {
            return AjaxResult.success("注册成功");
        }
        return AjaxResult.error("注册失败,请稍后重试");
    }

    @ApiOperation(value = "找回/重置密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "密码", value = "accountPassword", paramType = "String", required = true),
            @ApiImplicitParam(name = "手机号", value = "phone", paramType = "String", required = true),
            @ApiImplicitParam(name = "验证码", value = "code", paramType = "String", required = true)
    })
    @PostMapping("/resetPassword")
    public AjaxResult resetPassword(@RequestBody CustomerInfoAccountVo account) {
        String userName = account.getAccountName();
        String userPassword = account.getAccountPassword();
        String phone = account.getPhone();

        if (StringUtils.isEmpty(userPassword)) {
            throw new CustomException("密码不能为空");
        }
        if (StringUtils.isEmpty(phone)) {
            throw new CustomException("手机号码不能为空");
        }
        Boolean isCrate = customerInfoAccountService.resetCustomerPassword(account);
        if (isCrate) {
            return AjaxResult.success("修改成功，请前往登录页面进行登录。");
        }
        return AjaxResult.error("修改失败,请稍后重试");
    }


    /**
     * 找回密码

    @ApiOperation(value = "找回密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "密码", value = "accountPassword", paramType = "String", required = true),
            @ApiImplicitParam(name = "手机号", value = "phone", paramType = "String", required = true),
            @ApiImplicitParam(name = "验证码", value = "code", paramType = "String", required = true)
    })
    @PostMapping("/retrievePwd")
    public AjaxResult customerRetrievePwd(@RequestBody CustomerInfoAccountVo account) {
        String userPassword = account.getAccountPassword();
        String phone = account.getPhone();
        if (StringUtils.isEmpty(userPassword)) {
            throw new CustomException("密码不能为空");
        }
        if (StringUtils.isEmpty(phone)) {
            throw new CustomException("手机号码不能为空");
        }
        Boolean isRetrieve = customerInfoAccountService.retrievePwd(account);
        if (isRetrieve) {
            return AjaxResult.success("找回密码成功");
        }
        return AjaxResult.error("找回密码失败");
    }
     */

    @ApiOperation(value = "客户登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "用户名", value = "accountName", paramType = "String", required = true),
            @ApiImplicitParam(name = "密码", value = "accountPassword", paramType = "String", required = true)
    })
    @PostMapping(value = "login")
    public AjaxResult customerLogin(@RequestBody CustomerInfoAccountVo account) {
        String userName = account.getAccountName();
        String userPassword = account.getAccountPassword();
        if (StringUtils.isEmpty(userName)) {
            throw new CustomException("用户名不能为空");
        }
        if (StringUtils.isEmpty(userPassword)) {
            throw new CustomException("密码不能为空");
        }
        CustomerInfoAccount accountInfo = customerInfoAccountService.login(account);
        if (accountInfo == null) {
            throw new CustomException("用户名或密码错误！");
        }
        CustomerInfoAccountToken token = customerInfoAccountTokenService.createAccountInfoToken(accountInfo);
        if (token != null) {
            return AjaxResult.success("登录成功", token.getAccessToken());
        } else {
            return AjaxResult.error("登录失败，请稍后重试");
        }
    }

    @VerifyAuthorize()
    @RequestMapping(value = "userInfo")
    public AjaxResult customerInfo() {
        return AjaxResult.success();
    }


    /**
     * 微信扫码登录
     *
     * @param
     * @return
     */
    @ApiOperation(value = "微信扫码登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "code", paramType = "String", required = true)
    })
    @PostMapping(value = "wxLogin")
    public AjaxResult weiXinLogin(@RequestBody CustomerInfoAccountVo customerInfoAccountVo) {
        //调用微信公众号登录
        customerInfoAccountVo.setAppid(SecurityUtils.getCustomerAppId());
        //获取用户登录传过来的appid
        if (StringUtils.isEmpty(customerInfoAccountVo.getAppid())) {
            //throw new WechatException("appid不能为空");
        }
        //customerInfoAccountVo.setCode("031GeM100I5vPU1dmX1005GOcx3GeM1i");
        if (StringUtils.isEmpty(customerInfoAccountVo.getCode())) {
            throw new WechatException("code不能为空");
        }
        logger.info("微信扫码 开始根据code授权");
        CustomerInfoAccountVo infoAccountVo = wechatAuthorizationInfoService.wechatAllworkLogin(customerInfoAccountVo);
        if (infoAccountVo == null) return AjaxResult.error("登录失败，请稍后重试");
        if (!StringUtils.isEmpty(infoAccountVo.getOpenId())) {

            String token = customerInfoAccountService.allworkLogin(infoAccountVo);
            return AjaxResult.success("登录成功", token);
        } else {
            return AjaxResult.error("登录失败，请稍后重试");
        }
    }

    /**
     * 获取手机号登录
     */
    @ApiOperation(value = "获取手机号登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "encrypdata", value = "encrypdata", paramType = "String", required = true),
            @ApiImplicitParam(name = "iv", value = "iv", paramType = "String", required = true)
    })
    @PostMapping("/gainCustomerInfo")
    public AjaxResult GainCustomerInfo(@RequestBody CustomerInfoAccountVo customerInfoAccountVo) throws Exception {
        String rst = customerInfoAccountService.gainCustomerInfo(customerInfoAccountVo);
        Object rstObj = rst;
        return AjaxResult.success(rstObj);
    }

    /**
     * 通过微信获取手机号码
     */
    @ApiOperation(value = "通过微信获取手机号码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "encrypdata", value = "encrypdata", paramType = "String", required = true),
            @ApiImplicitParam(name = "iv", value = "iv", paramType = "String", required = true)
    })
    @PostMapping("/gainPhone")
    @VerifyAuthorize
    public AjaxResult gainPhone(@RequestBody CustomerInfoAccountVo customerInfoAccountVo) throws Exception {
        String rst = customerInfoAccountService.gainPhone(customerInfoAccountVo);
        Object rstObj = rst;
        return AjaxResult.success(rstObj);
    }


    /**
     * 更新用户信息
     */
    @ApiOperation(value = "更新用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "customerName", value = "客户名称", paramType = "String", required = true),
            @ApiImplicitParam(name = "headImage", value = "头像", paramType = "String", required = true),
            @ApiImplicitParam(name = "sex", value = "性别", paramType = "String", required = true),
            @ApiImplicitParam(name = "nation", value = "国籍", paramType = "String", required = true),
            @ApiImplicitParam(name = "province", value = "省份", paramType = "String", required = true),
            @ApiImplicitParam(name = "city", value = "城市", paramType = "String", required = true),
    })
    @PostMapping("/updateCustomerInfo")
    public AjaxResult UpdateCustomerInfo(@RequestBody CustomerInfo customerInfo) {
        Object rst = customerInfoService.editCustomerInfo(customerInfo);
        return AjaxResult.success(rst);
    }

    /**
     * 获取用户信息
     */
    @ApiOperation(value = "获取用户信息")
    @GetMapping("/getCustomerInfo")
    //@VerifyAuthorize
    public AjaxResult getCustomerInfo() {
        if(SecurityUtils.getCustomerUid() == null){
            return AjaxResult.success();
        }
        CustomerInfoVo customerInfo = customerInfoAccountService.getCustomerInfo();
        return AjaxResult.success(customerInfo);
    }

    @ApiOperation(value = "首页获取用户简单信息")
    @GetMapping("/getCustomerSimpleInfo")
    @VerifyAuthorize
    public AjaxResult getCustomerSimpleInfo(BaseQuery query) {
        CustomerInfoVo customerInfo = customerInfoAccountService.getCustomerSimpleInfo(query);
        return AjaxResult.success(customerInfo);
    }


    /**
     * 手机号登录
     */
    @ApiOperation(value = "手机号登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号", paramType = "String", required = true),
            @ApiImplicitParam(name = "code", value = "验证码", paramType = "String", required = true),
    })
    @PostMapping("/PhoneLogin")
    public AjaxResult PhoneLogin(@RequestBody CustomerPhoneLoginVo customerPhoneLoginVo) {
        String rst = customerInfoAccountService.PhoneLogin(customerPhoneLoginVo);
        if (!StringUtils.isEmpty(rst)) {
            return AjaxResult.success("登录成功", rst);
        } else {
            return AjaxResult.success("登录失败");
        }
    }

    /**
     * 修改客户信息
     */
    @ApiOperation(value = "修改客户信息")
    @PostMapping("/editCustomerInfo")
    @VerifyAuthorize
    public AjaxResult editCustomerInfo(@RequestBody CustomerInfoVo customerInfoVo) {
        return toAjax(customerInfoService.updateCustomerInfo(customerInfoVo));
    }

    /**
     * 我的-积分详细
     */
    @ApiOperation(value = "我的-积分详细")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前页", paramType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "总条数", paramType = "Integer", required = true)
    })
    @GetMapping("/getAllScoreDetail")
    @VerifyAuthorize
    public AjaxResult getAllScoreDetail(CustomerFundDetail customerFundDetail) {
        customerFundDetail.setDataStatus(DataStatus.valid.getKey());
        customerFundDetail.setBizType(CustomerFundBizTypeEnum.score.getKey());
        startPage();
        List<CustomerFundDetail> queryFundDetail = customerFundDetailService.selectMyFundDetail(customerFundDetail);
        Integer queryFundDetailCount = customerFundDetailService.selectMyFundDetailCount(customerFundDetail);
        CustomerFund fund = customerFundService.getByCustomerId(SecurityUtils.getCustomerUid());
        Map<String,Object> map = new HashMap<>();
        map.put("jifenTotal",fund);
        map.put("jifenList",queryFundDetail);
        return AjaxResult.successs(map, queryFundDetailCount);
    }


    /**
     * 我的-会员信息
     */
    @ApiOperation(value = "我的-会员信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前页", paramType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "总条数", paramType = "Integer", required = true)
    })
    @GetMapping("/getCustomerLevelInfo")
    public AjaxResult getCustomerLevelInfo() {
        startPage();
        List<CustomerLevelOpenVo> customerLevelInfo = customerLevelService.getCustomerLevelInfo();
        Integer customerLevelInfoCount = customerLevelService.getCustomerLevelInfoCount();
        return AjaxResult.successs(customerLevelInfo, customerLevelInfoCount);
    }


    @VerifyAuthorize
    @ApiOperation(value = "会员权益-会员等级-权益")
    @GetMapping("/levelAndPrivilege")
    public AjaxResult levelAndPrivilege() {
        List<CustomerPrivilegeOpenVo> rst = new ArrayList<>();
        Long levelId = 0L;
        List<CustomerLevel> list = customerLevelService.selectCustomerLevelAndRight(SecurityUtils.getCustomerUid());
        if (list.size()>0){
            CustomerPrivilegeOpenVo vo = new CustomerPrivilegeOpenVo();
            vo.setPrivilegeShowName("会员等级");
            vo.setPrivilegeValue(list.get(0).getLevelName());
            levelId = list.get(0).getLevelId();
            rst.add(vo);
        }
        CustomerFund fund = customerFundService.getByCustomerId(SecurityUtils.getCustomerUid());
        if (fund != null){
            if (fund.getFreezeRedBag() == null){
                fund.setFreezeRedBag(0L);
            }
            CustomerPrivilegeOpenVo vo = new CustomerPrivilegeOpenVo();
            vo.setPrivilegeShowName("积分权益");
            vo.setPrivilegeValue(String.valueOf(fund.getAllScore()));
            vo.setPlatformUnit("积分");
            vo.setUpgradeGiftBag(String.valueOf(fund.getScore()-fund.getFreezeScore()));
            rst.add(vo);
            //if (fund.getAllRedBag()>0){
                vo = new CustomerPrivilegeOpenVo();
                vo.setPrivilegeShowName("免费排版次数");
                vo.setPrivilegeValue(String.valueOf(fund.getAllRedBag()));
                vo.setPlatformUnit("次");
                vo.setUpgradeGiftBag(String.valueOf(fund.getRedBag()-fund.getFreezeRedBag()));
                rst.add(vo);
            //}
        }
        if (levelId >0) {
            CustomerLevelVo clvo = customerLevelService.getlevelInfoDetail(levelId);
            List<CustomerLevelPrivleageVo> clpList = clvo.getCustomerLevelPrivleageVos();
            for (CustomerLevelPrivleageVo c:clpList) {
                if (c.getPrivleageName().equalsIgnoreCase("points") || c.getPrivleageName().equalsIgnoreCase("paiban")){
                    continue;
                }
                CustomerPrivilegeOpenVo vo = new CustomerPrivilegeOpenVo();
                vo.setPrivilegeShowName(c.getPrivleageShowName());
                vo.setPrivilegeValue(c.getPrivilegeValue());
                rst.add(vo);
            }
        }
        return AjaxResult.success(rst);
    }


    /**
     * 查询抵扣列表信息
     */
    @ApiOperation(value = "查询抵扣列表信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前页", paramType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "总条数", paramType = "Integer", required = true)
    })

    @GetMapping("/getDeductList")
    @VerifyAuthorize
    public AjaxResult getDeductList(CustomerFundVo vo) {
        startPage();
        List<CustomerFundDetail> list = customerFundDetailService.selectDeduct(vo);
        return AjaxResult.successs(list,customerFundDetailService.selectDeductCount(vo));
    }


    /**
     * 确认抵扣
     */
    @VerifyAuthorize
    @ApiOperation(value = "确认抵扣")
    @PostMapping("/deduct/{detailUid}")
    public AjaxResult deduct(@PathVariable("detailUid") Long detailUid) {
        CustomerFundDetail cfd = customerFundDetailService.getById(detailUid);
        if (cfd == null){
            return AjaxResult.success("没有找到相关信息");
        }
        if (!cfd.getDataStatus().equals(DataStatus.invalid.getKey())){
            return AjaxResult.success("数据状态不正确，请刷新再试！");
        }
        if (!(cfd.getCustomerUid().longValue()==SecurityUtils.getCustomerUid())){
            return AjaxResult.success("没有找到相关信息！");
        }
        try {
            customerFundService.confirmDeduction(cfd);
        }catch (Exception e){
            return AjaxResult.success("确认失败，请稍后重试！");
        }
        return AjaxResult.success("确认成功！");

    }

}
